package cc.rengu.igas.share.common.util;

import cc.rengu.oltp.utility.util.RandomUtil;
import cc.rengu.oltp.utility.util.StringUtil;

import java.io.Serializable;
import java.util.Map;

public class SensitiveDataUtil implements Serializable {
    /**
     * 根据敏感信息类型对敏感信息进行脱敏处理
     *
     * @param dataType      敏感信息类型
     *                      1 - 手机号，脱敏规则：前3后4，中间全部用*代替
     *                      2 - 银行账号，脱敏规则：前6后4，中间全部用*代替
     *                      3 - 证件信息，脱敏规则：前6后4，中间全部用*代替
     *                      4 - 姓名，脱敏规则：前1后1，中间全部用*代替
     *                      5 - 邮箱，脱敏规则：@字符前的字符串，当大于3位时，前3位保留，后面补3个*，若小于3位，则@前的信息全显示，后面补3个*
     * @param sensitiveData 敏感信息
     * @return 脱敏后的敏感信息
     */
    public static String desensitization(String dataType, String sensitiveData) {
        if (StringUtil.isEmptyOrNull(sensitiveData)) {
            return "";
        }
        String sensitiveValue;
        switch (dataType) {
            case "1":
                sensitiveValue = sensitiveDataConvert(sensitiveData, 3, sensitiveData.length() - 4);
                break;
            case "2":
                sensitiveValue = sensitiveDataConvert(sensitiveData, 6, sensitiveData.length() - 4);
                break;
            case "3":
                sensitiveValue = sensitiveDataConvert(sensitiveData, 6, sensitiveData.length() - 4);
                break;
            case "4":
                sensitiveValue = sensitiveDataConvert(sensitiveData, 1, sensitiveData.length() - 1);
                break;
            case "5":
                int index = sensitiveData.indexOf("@");
                if (index < 0) {
                    return "";
                }
                if (sensitiveData.substring(0, index).length() > 3) {
                    sensitiveValue = sensitiveData.substring(0, 3) + "***" + sensitiveData.substring(index);
                } else {
                    sensitiveValue = sensitiveData.substring(0, index) + "***" + sensitiveData.substring(index);
                }
                break;
            default:
                sensitiveValue = sensitiveDataConvert(sensitiveData, 4, sensitiveData.length() - 4);
                break;
        }
        return sensitiveValue + "|" + RandomUtil.getUUID();
    }

    /**
     * 脱敏数据还原
     *
     * @param sensitiveData 已脱敏的敏感信息
     * @param sensitiveMap  会话SESSION中保存的脱敏数据集合
     * @return 还原后的数据
     */
    public static String reducition(String sensitiveData, Map<String, String> sensitiveMap) {
        return sensitiveMap.get(sensitiveData);
    }

    /**
     * 敏感信息转换
     * 当需要脱敏的数据长度小于或等于脱敏起始位置时，除最后1位保留原值包，前面部分全部替换成6个*
     * 当需要脱敏的数据长度大于脱敏起始位置时，再判断脱敏截止位置：
     * 若脱敏截止位置小于0或者脱敏开始位置大于等于脱敏截止位置时，则直接从脱敏起始位置进行脱敏，保留起始位置前的数据为原始数据，后面全部替换成6个*
     * 若脱敏截止位置大于0或者脱敏开始位置+脱敏截止位置之和小于待脱敏数据的长度时，按字符将待脱敏的字符替换成*
     *
     * @param sensitiveData 脱敏前的敏感信息
     * @param beginIndex    脱敏开始位置
     * @param endIndex      胶敏感截止位置
     * @return 脱敏后的数据
     */
    private static String sensitiveDataConvert(String sensitiveData, int beginIndex, int endIndex) {
        if (sensitiveData.length() <= beginIndex) {
            StringBuilder stringBuilder = new StringBuilder(sensitiveData);
            return stringBuilder.replace(0, sensitiveData.length() - 1, "******").toString();
        } else {
            if (endIndex < 0 || beginIndex >= endIndex) {
                StringBuilder stringBuilder = new StringBuilder(sensitiveData);
                return stringBuilder.replace(beginIndex, sensitiveData.length(), "******").toString();
            } else {
                StringBuilder stringBuffer = new StringBuilder(sensitiveData.substring(0, beginIndex));
                for (int index = beginIndex; index < endIndex; index++) {
                    stringBuffer.append("*");
                }
                stringBuffer.append(sensitiveData.substring(endIndex));
                return stringBuffer.toString();
            }
        }
    }
}
